/**
 * Witontek.com.
 * Copyright (c) 2012-2018 All Rights Reserved.
 */
package com.witon.bfb;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.witon.bfb.vo.BfbUser;
import com.witon.bfb.vo.Feed;
import com.witon.bfb.vo.FeedDetail;
import com.witon.bfb.vo.Forum;
import com.witon.bfb.vo.Subject;

/**
 * 
 * @author Long
 * @version $Id: BftIndex.java, v 0.1 2018年11月12日 上午11:02:03  xiaolong.ma  Exp $
 */
public class BfbIndex {

    private static final Logger logger     = LoggerFactory.getLogger(BfbIndex.class);

    private CloseableHttpClient httpClient;

    private String              XSRF_TOKEN = "";

    private String              message    = "赞,好,hao,好好,讲得好,非常赞,";

    public void start(List<BfbUser> userList) throws Exception {
        if (CollectionUtils.isEmpty(userList)) {
            return;
        }
        for (BfbUser user : userList) {
            index(user);
        }
    }

    public void index(BfbUser user) throws Exception {
        CookieStore cookieStore = new BasicCookieStore();
        httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
        String userUrl = "http://bfbjiaoyu.cn/user";
        HttpGet get = new HttpGet(userUrl);
        get.setHeader("User-Agent", Constant.BFB_AGENT);
        HttpResponse response = httpClient.execute(get);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        //System.out.println(result);

        List<Cookie> cookies = cookieStore.getCookies();
        for (int i = 0; i < cookies.size(); i++) {
            if (cookies.get(i).getName().equals("XSRF-TOKEN")) {
                XSRF_TOKEN = cookies.get(i).getValue();
                logger.info("XSRF-TOKEN:" + XSRF_TOKEN);
            }

        }

        //login
        HttpPost httpPost = new HttpPost("http://bfbjiaoyu.cn/login");
        httpPost.setHeader("User-Agent", Constant.BFB_AGENT);
        Map<String, String> personMap = new HashMap<String, String>();
        personMap.put("xsrfToken", XSRF_TOKEN);
        personMap.put("username", user.getUsername());
        personMap.put("password", user.getPassword());
        List<NameValuePair> list = new LinkedList<NameValuePair>();
        for (Entry<String, String> entry : personMap.entrySet()) {
            list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, "utf-8");
        httpPost.setEntity(formEntity);
        HttpResponse httpresponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpresponse.getEntity();
        result = EntityUtils.toString(httpEntity, "utf-8");
        //System.out.println("222:" + result);

        {
            String s = httpGet(userUrl, false);
            // logger.info(s);
        }

        {
            String listUrl = Constant.BFB_URL + "/forum?_pjax=#content";
            String s = httpGet(listUrl, true);
            // logger.info(s);
        }
        //社区回复
        fourm(20);
        //点赞教师朋友圈
        teacherFeed(19);

        //签到
        String signUrl = Constant.BFB_URL + "/sign/count/update?type=sign";

        get = new HttpGet(signUrl);
        get.setHeader("User-Agent", Constant.BFB_AGENT);
        response = httpClient.execute(get);
        entity = response.getEntity();
        result = EntityUtils.toString(entity, "UTF-8");
        System.out.println("TTT:" + result);
    }

    private void fourm(int count) {
        int postCount = 0;
        Set<String> set = new HashSet<>();
        for (int i = 3; i < 9; i++) {
            String listUrl = Constant.BFB_URL + "/forum/list?page=" + i;
            String s = httpGet(listUrl, true);
            logger.info(s);
            Forum forum = convert(s, Forum.class);
            logger.info("forum={}", forum);
            for (Subject subject : forum.getThreads()) {
                if (set.contains(subject.getTid())) {
                    continue;
                } else {
                    set.add(subject.getTid());
                }
                String url = Constant.BFB_URL + "/forum/view/" + subject.getTid()
                             + "?_pjax=#content_forumlist&_=" + System.currentTimeMillis();

                String subStr = httpGet(url, false);
                logger.info("subStr={},{}", subject.getSubject(), subStr);
                //回复
                String postUrl = Constant.BFB_URL + "/forum/comment/" + subject.getTid();
                Map<String, String> map = new HashMap<>();
                map.put("message", getMessage());
                map.put("xsrfToken", XSRF_TOKEN);
                String postRet = httpPost(postUrl, map);
                postCount++;
                //控制教师回复次数
                if (postCount > count) {
                    return;
                }
                try {
                    Thread.sleep(getSleepTime() * 1000);
                } catch (InterruptedException e) {
                    logger.error("", e);
                }
                //  logger.info("postRet={}", postRet);
            }

        }
    }

    //教师朋友圈
    private void teacherFeed(int count) {
        int postCount = 0;
        Set<String> set = new HashSet<>();
        for (int i = 2; i < 5; i++) {
            String listUrl = Constant.BFB_URL + "/feed/list?page=" + i;
            String s = httpGet(listUrl, true);
            Feed feed = convert(s, Feed.class);
            logger.info("forum={}", feed);
            for (FeedDetail fd : feed.getThreads()) {
                if (set.contains(fd.getTid())) {
                    continue;
                } else {
                    set.add(fd.getTid());
                }
                //回复
                String postUrl = Constant.BFB_URL + "/feed/comment/" + fd.getTid();
                Map<String, String> map = new HashMap<>();
                map.put("message", getMessage());
                map.put("xsrfToken", XSRF_TOKEN);
                String postRet = httpPost(postUrl, map);
                postCount++;
                //控制教师回复次数
                if (postCount > count) {
                    return;
                }
                try {
                    Thread.sleep(getSleepTime() * 1000);
                } catch (InterruptedException e) {
                    logger.error("", e);
                }
                logger.info("postRet={}", postRet);
            }
        }
    }

    private String getMessage() {
        String[] arr = message.split(",");
        Random random = new Random();
        int i = random.nextInt(arr.length - 1);
        return arr[i];
    }

    private int getSleepTime() {
        Random random = new Random();
        int i = random.nextInt(10);
        return 5 + i;
    }

    private <T> T convert(String s, Class clazz) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        T f = null;
        try {
            f = (T) mapper.readValue(s, clazz);

        } catch (Exception e) {
            logger.error("{}", e);
        }
        return f;
    }

    private String httpGet(String url, boolean isAjax) {

        try {
            HttpGet get = new HttpGet(url);
            get.setHeader("User-Agent", Constant.BFB_AGENT);
            if (isAjax) {
                get.addHeader("X-Requested-With", "XMLHttpRequest");
            }
            HttpResponse response;
            response = httpClient.execute(get);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, "UTF-8");
        } catch (ClientProtocolException e) {
            logger.error("", e);
        } catch (IOException e) {
            logger.error("", e);
        }
        return "error";
    }

    private String httpPost(String url, Map<String, String> map) {
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("User-Agent", Constant.BFB_AGENT);

            List<NameValuePair> list = new LinkedList<NameValuePair>();
            for (Entry<String, String> entry : map.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, "utf-8");
            httpPost.setEntity(formEntity);
            HttpResponse httpresponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpresponse.getEntity();
            return EntityUtils.toString(httpEntity, "utf-8");
        } catch (ClientProtocolException e) {
            logger.error("", e);
        } catch (IOException e) {
            logger.error("", e);
        }
        return "error";
    }

}
